package com.lc.activiti.process;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lc.activiti.config.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.List;

/**
 * 流程控制层
 * @author: 骆超
 * @date: 2021/5/27 16:29
 */
@RestController
@RequestMapping("/processDefinition")
@Api(tags = "流程控制")
@Slf4j
public class ProcessDefinitionController {

    @Resource
    private RepositoryService repositoryService;


    /**
     * 流程部署
     * @author 骆超
     * @date 2021/5/27
     * @param bpmnBean bpmn对象
     * @return com.lc.activiti.config.Result
     */
    @PostMapping(value = "/addDeploymentByString")
    @ApiOperation("流程部署")
    public Result addDeploymentByString(@RequestBody BpmnBean bpmnBean) {
        try {
            String bpmnStr = bpmnBean.getBpmnStr().replace("camunda:","activiti:");
            bpmnStr = !bpmnStr.contains("xmlns:activiti=\"http://activiti.org/bpmn\"") ? bpmnStr.replace("xmlns:camunda=\"http://camunda.org/schema/1.0/bpmn\"","xmlns:activiti=\"http://activiti.org/bpmn\""):bpmnStr.replace("xmlns:camunda=\"http://camunda.org/schema/1.0/bpmn\"","");
            Deployment deployment = repositoryService.createDeployment()
                    .addString(bpmnBean.getResourceName(),bpmnStr)
                    .name(bpmnBean.getName())
                    .deploy();
//            taskRoleAuditService.save(new TaskRoleAudit().setTaskId());
            return Result.success(deployment.getId()).setMsg(bpmnBean.getName()+"部署流程成功！");
        } catch (Exception e) {
            return Result.failed(bpmnBean.getName()+"部署流程失败！");
        }
    }

    /**
     * 获取流程定义列表
     * @author 骆超
     * @date 2021/5/31
     * @param bpmnBean 参数说明
     * @return com.lc.activiti.config.Result
     */
    @PostMapping("getDefinitions")
    @ApiOperation("获取流程定义列表")
    public Result getDefinitions(@RequestBody BpmnBean bpmnBean){
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
        if (ObjectUtil.isNotEmpty(bpmnBean.getName())){
            processDefinitionQuery.processDefinitionNameLike("%"+bpmnBean.getName()+"%");
        }
        //获取分页参数
        Page page = bpmnBean.getPage();
        int startIndex = Math.toIntExact((page.getCurrent() - 1) * page.getSize());
        int endIndex = Math.toIntExact(page.getCurrent() * page.getSize());
        List<ProcessDefinition> list = processDefinitionQuery.listPage(startIndex,endIndex);
        page.setTotal(processDefinitionQuery.count());
        page.setRecords(JSONUtil.parseArray(list));
        //根据版本排序
        list.sort((y,x)->x.getVersion()-y.getVersion());
        return Result.success(page);
    }

    /**
     * 获取流程定义XML
     * @author 骆超
     * @date 2021/5/31
     * @param response 参数说明
     */
    @PostMapping(value = "/getDefinitionXml")
    @ApiOperation("获取流程定义XML")
    public Result getDefinitionXml(HttpServletResponse response, @RequestBody BpmnBean bpmnBean) {
        try {
            InputStream inputStream = repositoryService.getResourceAsStream(bpmnBean.getDeploymentId(), bpmnBean.getResourceName());
            return Result.success(IoUtil.readUtf8(inputStream).replace("activiti:","camunda:"));
        } catch (Exception e) {
            log.error(e.toString());
            return Result.failed("获取流程图失败！");
        }
    }

    /**
     * 根据流程部署id删除
     * @author 骆超
     * @date 2021/5/31
     * @param bpmnBean 参数说明
     * @return com.lc.activiti.config.Result
     */
    @PostMapping("delDefinition")
    @ApiOperation("根据流程部署id删除")
    public Result delDefinition(@RequestBody BpmnBean bpmnBean){
        try {
            repositoryService.deleteDeployment(bpmnBean.getDeploymentId(), true);
            return  Result.success(null).setMsg("删除成功!");
        } catch (Exception e) {
            return Result.failed("删除失败");
        }
    }
}
